﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace AdoNET
{
    class Adapter
    {
        private SqlConnection _cn;

        public Adapter()
        {
            _cn = new SqlConnection("Data Source=localhost;Initial Catalog=inventories;Integrated Security=True");
        }

        #region Method
        public bool Create(string productName, int price)
        {
            bool status = false;
            try
            {
                string query = "INSERT INTO Products (ProductName, Price) VALUES (@productName, @price)";
                SqlCommand cmd = new SqlCommand(query, _cn);
                cmd.Parameters.Add("productName", SqlDbType.VarChar).Value = productName;
                cmd.Parameters.Add("price", SqlDbType.Int).Value = price;
                cmd.ExecuteNonQuery();
                status = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("errors: {0}", ex.Message);
            }
            return status;
        }

        // 1. Method return list of products that have price < 200 and product name Bxxxx
        public IList<Product> Read()
        {
            IList<Product> products = new List<Product>();
            try
            {
                _cn.Open();
                string query = "SELECT * FROM Products WHERE Price < 200 AND ProductName LIKE 'B%'";
                SqlCommand cmd = new SqlCommand(query, _cn);
                SqlDataAdapter ad = new SqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                ad.Fill(ds);
                DataTable productTable = ds.Tables[0];
                foreach (DataRow row in productTable.Rows)
                {
                    Product product = new Product(Int32.Parse(row[0].ToString()), row[1].ToString(), Int32.Parse(row[2].ToString()));
                    products.Add(product);
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("errors: {0}", ex.Message);
                _cn.Close();
            }
            finally
            {
                _cn.Close();
            }
            return products;
        }

        // 2. Method return a product with productId = 3
        public Product FindByProductId(int productId)
        {
            Product product = new Product();
            try
            {
                _cn.Open();
                string query = "SELECT * FROM Products WHERE ProductId = @id";
                SqlCommand cmd = new SqlCommand(query, _cn);
                cmd.Parameters.Add("id", SqlDbType.Int).Value = productId;
                SqlDataAdapter ad = new SqlDataAdapter(cmd);
                DataSet ds = new DataSet();
                ad.Fill(ds);
                DataTable productTable = ds.Tables[0];
                foreach (DataRow row in productTable.Rows)
                {
                    product = new Product(Int32.Parse(row[0].ToString()), row[1].ToString(), Int32.Parse(row[2].ToString()));
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("errors: {0}", ex.Message);
                _cn.Close();
            }
            finally
            {
                _cn.Close();
            }
            return product;
        }

        // 3. Method update a product, and return the product
        public Product UpdateByProductId(int productId, int price)
        {
            Product product = new Product();
            try
            {
                _cn.Open();
                string updateQuery = "UPDATE Products SET Price = @price WHERE ProductId = @productId";
                string selectQuery = "SELECT * FROM Products WHERE productId = @productId";
                SqlCommand cmd = new SqlCommand(updateQuery, _cn);
                SqlCommand cmd2 = new SqlCommand(selectQuery, _cn);
                cmd.Parameters.Add("productId", SqlDbType.Int).Value = productId;
                cmd.Parameters.Add("Price", SqlDbType.Int).Value = price;
                cmd2.Parameters.Add("productId", SqlDbType.Int).Value = productId;
                SqlDataAdapter ad = new SqlDataAdapter(cmd2);
                DataSet ds = new DataSet();
                cmd.ExecuteNonQuery();
                ad.Fill(ds);
                DataTable productTable = ds.Tables[0];
                foreach (DataRow row in productTable.Rows)
                {
                    product = new Product(Int32.Parse(row[0].ToString()), row[1].ToString(), Int32.Parse(row[2].ToString()));
                }

            }
            catch (Exception ex)
            {
                Console.WriteLine("errors: {0}", ex.Message);
                _cn.Close();
            }
            finally
            {
                _cn.Close();
            }
            return product;
        }

        // 4. Method update a product with product name = Exxxx (use transaction to cancel the update), and return boolean
        public bool UpdateByProductName(string productName, int price) 
        {
            bool status = false;
            using (SqlConnection _cn = new SqlConnection("Data Source=localhost;Initial Catalog=inventories;Integrated Security=True"))
            {
                _cn.Open();

                SqlCommand command = _cn.CreateCommand();
                SqlTransaction transaction;
                transaction = _cn.BeginTransaction("Transaction");
                command.Connection = _cn;
                command.Transaction = transaction;

                try
                {
                    command.CommandText = "UPDATE Products SET Price = @price WHERE ProductName = @productName";
                    command.Parameters.Add("productName", SqlDbType.VarChar).Value = productName;
                    command.Parameters.Add("price", SqlDbType.Int).Value = price;
                    command.ExecuteNonQuery();

                    transaction.Commit();
                    status = true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("  Message1: {0}", ex.Message);
                    try
                    {
                        transaction.Rollback();
                    }
                    catch (Exception ex2)
                    {
                        Console.WriteLine("  Message2: {0}", ex2.Message);
                    }
                    status = false;
                }
            }
            return status;
        }

        // 5. Method delete a product
        public void Delete(int productId)
        {
            try
            {
                _cn.Open();
                string updateQuery = "DELETE Products WHERE ProductId = @productId";
                SqlCommand cmd = new SqlCommand(updateQuery);
                cmd.Connection = _cn;
                cmd.Parameters.Add("productId", SqlDbType.Int).Value = productId;
                cmd.ExecuteNonQuery();

            }
            catch (Exception ex)
            {
                Console.WriteLine("errors: {0}", ex.Message);
                _cn.Close();
            }
            finally
            {
                _cn.Close();
            }
        }
        #endregion

    }
}
